package inv.cal;

import inv.cal.logic.EventsInfo;
import inv.cal.logic.Manager;
import inv.cal.view.CalendarTableColumnModel;
import inv.cal.view.CalendarTableModel;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;

public class DatePickerDialog extends JDialog {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JPanel jHeaderPanel = null;
	private JTable jCalendarTable = null;
	private AbstractTableModel jCalendarTableModel;
	private JComboBox jMonthBox = null;
	private JComboBox jYearBox = null;
	
	private Manager manager;
	
	/**
	 * @param owner
	 */
	public DatePickerDialog(Frame owner, Manager manager) {
		super(owner);
		setModal(true);
		setResizable(false);

		this.manager = manager;
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		addCancelByEscapeKey();
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJHeaderPanel(), BorderLayout.NORTH);
			
			JPanel tablePanel			= new JPanel(new BorderLayout());
			tablePanel.add(getJCalendarTable().getTableHeader(), BorderLayout.NORTH);
			tablePanel.add(getJCalendarTable(), BorderLayout.CENTER);
			jContentPane.add(tablePanel, BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jHeaderPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJHeaderPanel() {
		if (jHeaderPanel == null) {
			jHeaderPanel = new JPanel();
			jHeaderPanel.setLayout(new GridLayout(1, 2));
			jHeaderPanel.add(getJMonthBox());
			jHeaderPanel.add(getJYearBox());
		}
		return jHeaderPanel;
	}

	/**
	 * This method initializes jCalendarTable	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getJCalendarTable() {
		if (jCalendarTable == null) {
			jCalendarTableModel	= new CalendarTableModel(manager);
			CalendarTableColumnModel columnModel	= new CalendarTableColumnModel();

			jCalendarTable = new JTable(jCalendarTableModel, columnModel);
			jCalendarTable.createDefaultColumnsFromModel();
			jCalendarTable.setCellSelectionEnabled(true);
			jCalendarTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
			jCalendarTable.addMouseListener(
					new MouseAdapter(){
						@Override
						public void mouseClicked(MouseEvent e) {
							if (e.getClickCount() == 2){
								closeDialog();
						    }
						}
					});
			
			columnModel.updateColumnRenderers(manager);
			updateMonthAndYear();
		}
		return jCalendarTable;
	}
	
	private void closeDialog() {
		setVisible(false);
	}
	
	private void updateMonthAndYear(){
		jYearBox.setSelectedItem(manager.getSelectedYear());
		jMonthBox.setSelectedIndex(manager.getSelectedMonthIndex());
	}
	

	/**
	 * This method initializes jMonthBox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getJMonthBox() {
		if (jMonthBox == null) {
			jMonthBox = new JComboBox();
			List<String> months	= manager.getMonths();
			for(String month: months)
				jMonthBox.addItem(month);
			
			jMonthBox.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					JComboBox box = (JComboBox)e.getSource();
					int selectedIndex = box.getSelectedIndex();
					manager.setMonth(selectedIndex);
					jCalendarTableModel.fireTableDataChanged();
				}
			});
		}
		return jMonthBox;
	}

	/**
	 * This method initializes jYearBox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getJYearBox() {
		if (jYearBox == null) {
			jYearBox = new JComboBox();
			List<Integer> years	= manager.getYears();
			for(Integer year: years)
				jYearBox.addItem(year);
			
			jYearBox.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					JComboBox box = (JComboBox)e.getSource();
					int selectedValue = (Integer)box.getSelectedItem();
					manager.setYear(selectedValue);
					jCalendarTableModel.fireTableDataChanged();
				}
			});
		}
		return jYearBox;
	}

	private void selectCurrentDate(Date date){
		int year	= manager.getFromDate(date, Calendar.YEAR);
		int month	= manager.getFromDate(date, Calendar.MONTH);
		
		jYearBox.setSelectedItem(year);
		jMonthBox.setSelectedIndex(month);
		manager.setSelectedDate(date);
		jCalendarTableModel.fireTableDataChanged();
	}
	
	public void updateEvents(List<EventsInfo> events, Date selectDate){
		manager.clearEvents();
		manager.addAll(events);
		manager.calculateYearsByEvents();
		selectCurrentDate(selectDate);
	}
	
	public Date getReturnValue(){
		return manager.getReturnDate();
	}
	
	  private void addCancelByEscapeKey(){
		    String CANCEL_ACTION_KEY = "CANCEL_ACTION_KEY";
		    int noModifiers = 0;
		    KeyStroke escapeKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, noModifiers, false);
		    InputMap inputMap = 
		      this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
		    ;
		    inputMap.put(escapeKey, CANCEL_ACTION_KEY);
		    AbstractAction cancelAction = new AbstractAction(){
				private static final long serialVersionUID = 2252249983664517878L;

			public void actionPerformed(ActionEvent e){
				manager.setReturnDate(null);
		        closeDialog();
		      }
		    }; 
		    this.getRootPane().getActionMap().put(CANCEL_ACTION_KEY, cancelAction);
		  }


}
